/*
 * Copyright 2010 Christoph Widulle (christoph.widulle@googlemail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */



package com.android1.amarena2d.commons.collections;


/**
 * NOT Threadsafe.
 */
public class FixedSizeStagingList<E> {

    private static final int STAGING_SIZE_REMOVE = 10;
    private static final int STAGING_SIZE_ADD = 10;
    private static final int SIZE = 30;

    private final FixedSizeQueue<E> toAdd;
    private final FixedSizeQueue<E> toRemove;
    private final FixedSizeArray<E> elements;

    public FixedSizeStagingList(int size) {
        this(size, size, size);
    }

    public FixedSizeStagingList(int size, int addSize, int removeSize) {
        toAdd = new FixedSizeQueue<E>(addSize);
        elements = new FixedSizeArray<E>(size);
        toRemove = new FixedSizeQueue<E>(removeSize);
    }

    public FixedSizeStagingList() {
        this(SIZE, STAGING_SIZE_ADD, STAGING_SIZE_REMOVE);
    }

    public void applyChanges() {
        E e;
        if (toRemove.length() > 0) {
            while ((e = toRemove.poll()) != null)
                elements.remove(e);
        }
        if (toAdd.length() > 0) {
            while ((e = toAdd.poll()) != null) {
                if (elements.find(e, true) == -1)
                    if (!elements.add(e))
                        throw new IndexOutOfBoundsException("FixedSizeStagingList is full.");
            }
        }
    }

    public final void add(E object) {
        if (!toAdd.add(object))
            throw new IndexOutOfBoundsException("FixedSizeStagingList is full.");
    }

    public void remove(E object) {
        if (!toRemove.add(object))
            throw new IndexOutOfBoundsException("FixedSizeStagingList is full.");
    }

    public void clear() {
        elements.clear();
        toAdd.clear();
        toRemove.clear();
    }

    public boolean contains(E object) {
        return elements.find(object, true) != -1;
    }

    public int getCount() {
        return elements.getCount();
    }

    public E get(int index) {
        return elements.get(index);
    }

    public FixedSizeArray<E> getElements() {
        return elements;
    }
}
